import DataBus from './databus';
import * as THREE from 'three';

const databus = new DataBus()
const game = databus.game


// 创建硬币
class Coin {
	constructor() {
		this.mesh = null; // 实例
		this.angle = 0; // 当前位置（0~2π）
		this.distance = 0; // 距离圆心半径

		this.draw()
	}

	// 硬币自转
	rotate() {
		this.angle += game.speed * game.coinsSpeed;
		this.mesh.rotation.z += Math.random() * .1;
		this.mesh.rotation.y += Math.random() * .1;
	}
	// 硬币前进（位置更新）
	setPosition() {
		this.mesh.position.y = -game.seaRadius + Math.sin(this.angle) * this.distance;
		this.mesh.position.x = Math.cos(this.angle) * this.distance;
	}

	draw() {
		const geom = new THREE.TetrahedronGeometry(5, 0);
		const mat = new THREE.MeshPhongMaterial({
			color: 0x009999,
			shininess: 0,
			specular: 0xffffff,
			shading: THREE.FlatShading
		});
		this.mesh = new THREE.Mesh(geom, mat);
		this.mesh.castShadow = true;
	}

	update() {
		this.rotate();
		this.setPosition();
	}
}

// 硬币列表
export default class CoinsHolder {
	constructor(n = 20) {
		this.mesh = new THREE.Object3D(); // 实例
		this.inUse = []; // 使用中的硬币
		this.pool = Array.from(Array(n), () => new Coin()); // 储存池中的硬币
	}

	// 添加硬币
	spawnCoins() {
		const nCoins = 5 + Math.floor(Math.random() * 5); // 5~10
		// 硬币平均高度（距离圆心长度）
		const d = game.seaRadius + game.planeDefaultHeight + (-1 + Math.random() * 2) * (game.planeAmpHeight - 20);
		const amplitude = -20 + Math.round(Math.random() * 40); // -20~20
		for (let i = 0; i < nCoins; -i++) {
			const coin = this.pool.length
				? this.pool.pop() // 储存池中有硬币，就用储存池中的
				: new Coin(); // 新建硬币实例

			coin.angle = - (i * 0.01) + 0.4 * Math.PI; // 设置硬币初始出现位置
			coin.distance = d + Math.cos(i * .5) * amplitude; // 硬币距离圆心距离
			coin.setPosition();

			this.mesh.add(coin.mesh); // 硬币集实例中添加硬币
			this.inUse.push(coin); // 使用中的硬币添加
		}
	}

	// 硬币前进和自转
	update() {
		this.inUse.forEach((coin, index) => {
			// 超过半圈的硬币回收
			if (coin.angle > Math.PI) {
				this.pool.unshift(this.inUse.splice(index, 1)[0]);
				this.mesh.remove(coin.mesh);
			}
			coin.update()
		})
	}
}